<!-- 现金支付 -->
<template>
  <view class="pay-page">
    <view class="title" v-if="props.title">{{ props.title }}</view>
    <view class="sub-title" v-if="props.subTitle">{{ props.subTitle }}</view>
    <view class="content">
      <input class="content-input" disabled v-model="payBean.amount" placeholder="请收入实收金额" />
      <!-- <u-input custom-style="background:red;" v-model="payBean.amount" placeholder="请收入实收金额" border="none" clearable /> -->
    </view>
    <view class="sub-title" v-if="props.modelMoney"> 应收：{{ payBean.money }} 元</view>
    <view v-else class="sub-title"></view>
    <!-- 正在支付遮罩层 -->
    <payMask ref="refPayMask" />
    <number-keyboard ref="refNumberKeyboard" @change="onKeyboardChange" :confirmText="props.confirmText" />

    <!-- 弹窗提示 - 主要用于显示一些错误信息 -->
    <resultPopup ref="refCommonPopup"> </resultPopup>
  </view>
</template>
<script setup>
import { reactive, ref, onMounted } from "vue";
import { payBuffetOrder } from "@/api";
import payMask from "./pay-mask.vue";
import resultPopup from "@/components/common-popup/result-popup.vue";
import { useStore } from "vuex";
import { placeAnOrder } from "./payUtils";
const store = useStore();
const refCommonPopup = ref();

const props = defineProps({
  title: {
    type: String,
    default: "现金收款",
  },
  subTitle: {
    type: String,
    default: "",
  },
  confirmText: {
    type: String,
    default: "确认收款",
  },
  // 应收款金额
  modelMoney: {
    type: [String, Number],
  },
  /** 跳过支付., 只做操作组件 */
  skipPayment: {
    type: Boolean,
    default: false,
  },
  // 自定义下单逻辑
  customizeOrder: {
    type: Function,
  },
});

const payBean = reactive({
  // 支付方式(此处指该组件的固定类型名称，用于区分收款结束时的展示状态)
  payType: "cash",
  // 支付状态  'reading' 'paying', 'success', 'fail', 'cancel'
  status: "paying",
  // 应收金额
  money: props.modelMoney,
  // 支付金额 （除了现金支付外，其他支付 支付金额 = 应收金额）
  amount: "",
  // 订单id
  orderId: "",
});

const emits = defineEmits(["pay-finish", "pay-clear"]);

// 支付状态
const payStatus = {
  status: "none",
  money: "",
  msg: "",
  code: "",
};

const refNumberKeyboard = ref();

const onKeyboardChange = async (val) => {
  const { type, name, key } = val;

  // 先判断是不是数字
  if (type === "number") {
    // 如果是小数点 且 已有小数点或当前为首位时，则不添加小数点
    if (name === "." && (payBean.amount.includes("\.") || payBean.amount === "")) return;
    // 如果是 0 开头，当前只能添加 .
    if (name !== "." && payBean.amount === "0") return;
    payBean.amount += name;
  } else if (type === "func") {
    switch (key) {
      case "delete":
        payBean.amount = payBean.amount.slice(0, -1);
        break;
      case "clear":
        payBean.amount = "";
        emits("pay-clear");
        break;
      case "ok":
        // 判断是否是一个正确的数字
        if (/* Number(payBean.amount) === 0 ||  */ isNaN(Number(payBean.amount))) {
          uni.showToast({ title: "请输入正确的实收金额", icon: "none" });
          return;
        }

        // 计算应收实收，如果实收大于应收，则计算并计算找零
        if (Number(payBean.amount) > Number(payBean.money)) {
          // 计算找零
        } else if (Number(payBean.amount) < Number(payBean.money)) {
          uni.showToast({ title: "实收金额不能小于应收金额", icon: "none" });
          return;
        }

        // 执行支付相关逻辑
        if (!props.skipPayment) {
          await placeAnOrderLogic();
        } else {
          payStatus.status = "success";
          // 逻辑执行成功后 结束收款
          uni.$emit("pay:finish", { type: payStatus.status, money: payBean.amount, payBean: payBean, result: {} });
          // 通知事件
          emits("pay-finish", { type: payStatus.status, money: payBean.amount, payBean: payBean, result: {} });
        }
        break;
    }
  } else {
    return;
  }

  // 其他规则

  if (payBean.amount === "0") {
    // 正则表达式判断非0的数字
    refNumberKeyboard.value.setItemDisable(/\d/, true);
  } else {
    refNumberKeyboard.value.setItemDisable(/\d/, false);
  }

  if (payBean.amount.includes("\.")) refNumberKeyboard.value.setItemDisable(/\./, true);
  else refNumberKeyboard.value.setItemDisable(/\./, false);
};

const clear = () => {
  payBean.amount = "";
};

const refPayMask = ref();

const statusTips = {
  cash: {
    placing: () => {
      payBean.infoTxt = "正在下单";
      payBean.errTxt = "";
      payBean.status = "placing";
    },
    paying: () => {
      payBean.infoTxt = "正在支付";
      payBean.errTxt = "";
      payBean.status = "paying";
    },
    success: (text) => {
      payBean.infoTxt = text || "收款成功";
      payBean.errTxt = "";
      payBean.status = "success";
    },
    fail: (errTxt, openPopup = false, reInitNfc = false) => {
      payBean.infoTxt = "";
      payBean.errTxt = errTxt || "现金收款失败";
      payBean.status = "fail";
      if (openPopup) {
        // 弹出错误提示框
        refCommonPopup.value.open({
          title: "失败",
          content: errTxt,
          type: "fail",
        });
      }
    },
  },
};

/* 下单逻辑 */
const placeAnOrderLogic = async () => {
  refPayMask.value.open();
  refPayMask.value.setDate("下单中", "请稍等...");

  // 自定义下单逻辑
  if (props.customizeOrder && typeof props.customizeOrder === "function") {
    try {
      await props.customizeOrder({ payBean, refPayMask: refPayMask.value });
    } catch (error) {
      console.error(error);
      refPayMask.value.close();
      statusTips.cash.fail(error?.data?.msg || error.message || "下单失败", true, true);
      // 重新抛出异常
      throw error;
    }
    return;
  }

  try {
    // 会员信息
    const memberInfo = store.getters.currShoppingCardInfo.member || {};

    const {
      data,
      success: isplaced,
      msg,
    } = await placeAnOrder({
      memberInfo: memberInfo,
      payType: "4",
      specialParam: {},
    });

    if (!isplaced) throw new Error(msg || "下单失败");
    // 下单成功后，执行支付逻辑

    // 订单号
    payBean.orderId = data.parentId;
    await payment(data.parentId);

    statusTips.cash.paying();
  } catch (error) {
    console.error(error);
    refPayMask.value.close();
    statusTips.cash.fail(error?.data?.msg || error.message || "下单失败", true, true);
    // 重新抛出异常
    throw error;
  }
};

/** 现金支付逻辑 */
const payment = async (orderId) => {
  refPayMask.value.setDate("支付中", "请等待支付结果");
  try {
    const pam = {
      payType: "4", // 支付方式（1余额2微信3支付宝4现金5套餐6刷卡(注意不是会员卡)7货到付款）
      parentId: orderId,
      // paymentBarcode: "", // 支付授权码 （// TODO 不清楚为什么现金支付需要授权码）
    };
    const { data, success } = await payBuffetOrder(pam);
    if (!success) throw new Error("支付失败");
    // （！！！payBuffetOrder 现金支付没有这个返回！！！） @payStatus  NO_PAY-待支付, FAIL-失败, SUCCESS-成功, CLOSE-支付关闭
    // if (data.payStatus != "SUCCESS") throw new Error(data.remark || "支付失败");
    refPayMask.value.close();
    statusTips.cash.success("支付成功");
    payFinsh(data);
  } catch (error) {
    if (error?.data?.msg == "订单已经支付请刷新") {
      statusTips.cash.success("订单已支付");
      return payFinsh({});
    }
    statusTips.cash.fail(error?.data?.msg || error.message || "支付失败", true, false);
    // 重新抛出异常
    throw error;
  }
};

// 支付结束
const payFinsh = async (result) => {
  statusTips.cash.success();
  refPayMask.value.close();
  uni.$emit("pay:finish", { type: payBean.status, money: payBean.amount, payBean: payBean, result });
  emits("pay-finish", { type: payBean.status, money: payBean.amount, payBean: payBean, result });
};

onMounted(() => {
  /**
   * 修改：自动赋值到金额键盘，去除人工二次输入确认
   * 附任务任务地址 http://172.10.0.21:30417/#/tasklist/index/8fe994fe876884ffcd40320d7277a78e/detail/1bf53fa0780d96a29678fe83c2ff0e5d
   */
  if (props.modelMoney && !isNaN(Number(props.modelMoney))) {
    payBean.amount = props.modelMoney;
  }
});

defineExpose({ clear });
</script>
<style lang="scss" scoped>
.pay-page {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  padding: 10rpx;
  width: 100%;
  box-sizing: border-box;

  .title {
    margin-top: 15rpx;
    font-weight: bold;
  }

  .sub-title {
    margin-top: 5rpx;
    font-size: 10rpx;
    color: lightgray;
  }

  .content {
    margin-top: 10rpx;
    font-size: 10rpx;

    .content-input {
      border: 1rpx solid #ccc;
      padding: 10rpx;
      // width: 100%;
      border-radius: 3rpx;
      font-size: 10rpx;
      font-weight: bold;
    }
  }
}
</style>
